package com.edu.framework.websocket.service;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.edu.framework.websocket.WebSocketHolder;
import com.edu.framework.websocket.assemble.message.MessageAssemble;
import com.edu.framework.websocket.assemble.message.TriggerMsgEngine;
import com.edu.framework.websocket.message.base.Message;
import com.edu.framework.websocket.message.base.Response;
import com.edu.framework.websocket.message.lessonremind.LessonRemindRequest;
import com.edu.framework.websocket.message.lessonremind.LessonRemindVO;
import com.edu.framework.websocket.message.lessonremind.LessonRemindVO.LessonRemindVOBuilder;
import com.edu.framework.websocket.message.timetable.TimetableVO;
import com.edu.framework.websocket.message.timetable.TimetableVO.TableVO;
import com.edu.system.service.ITTerminalService;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

/**
 * @program: xxxx
 * @description:
 * @author: zlh
 * @create: 2024-01-06 18:20
 **/
@Slf4j
@Component
public class LessonRemindService implements MessageAssemble {

  @Resource
  private TimetableService wsTimetableService;
  @Resource
  private ITTerminalService itTerminalService;

  public Response<LessonRemindVO> nowLessonRemind(Long classId){
    if (classId == null){
      return null;
    }
    Date date = new Date();
    TimetableVO timetable = wsTimetableService.getTimetable(classId, null, date);
    List<TableVO> tableVOS = timetable.getTimeTable();

    LessonRemindVOBuilder builder = LessonRemindVO.builder();

    // 查询 明日课程
    if (CollectionUtils.isEmpty(tableVOS)){
      String nextLessonTip = this.buildTomorrowLessonTip(classId, date);
      return Response.ok(LessonRemindRequest.TYPE, LessonRemindRequest.RESP_KEY,
          builder.nextLessonTip(nextLessonTip).build());
    }

    LocalTime now = LocalTime.now();
    TableVO nowLesson = null;
    TableVO nextLesson = null;
    for (int i=0;i<tableVOS.size();i++){
      TableVO a = tableVOS.get(i);
      if (LocalTime.parse(a.getStart()).isBefore(now) && LocalTime.parse(a.getEnd()).isAfter(now)){
        nowLesson = tableVOS.get(i);
      }
      if (nextLesson == null && LocalTime.parse(a.getStart()).isAfter(now)){
        nextLesson = tableVOS.get(i);
      }
    }
    // 当前时间 没有课程，则查明日课程
    if (nowLesson != null){
      builder
          .lesson(nowLesson.getLesson())
          .teacher(nowLesson.getTeacher())
          .start(this.getMillis(nowLesson.getStart()))
          .end(this.getMillis(nowLesson.getEnd()))
          .toOverTime(
              ChronoUnit.MINUTES.between(now, LocalTime.parse(nowLesson.getEnd())) + "分钟"
          );
    }
    // 如果当日有下一节
    if (nextLesson != null){
      builder.nextLessonTip("今天：" + nextLesson.getStartEnd() + " "+ nextLesson.getLesson());
    } else {
      builder.nextLessonTip(this.buildTomorrowLessonTip(classId, date));
    }

    LessonRemindVO vo = builder.build();
    return Response.ok(LessonRemindRequest.TYPE, LessonRemindRequest.RESP_KEY, vo);
  }

  /**
   *
   * @param classId
   * @param nowDate
   * @return
   */
  private String buildTomorrowLessonTip(Long classId, Date nowDate) {
    String nextLessonTip = null;
    TimetableVO nextTableVOs = wsTimetableService.getTimetable(classId, null, DateUtil.offsetDay(nowDate, 1));
    List<TableVO> nextTable = nextTableVOs.getTimeTable();
    if (CollectionUtils.isNotEmpty(nextTable)){
      TableVO tableVO = nextTable.get(0);
      nextLessonTip = "明天：" + tableVO.getStartEnd() + " "+ tableVO.getLesson();
    }
    return nextLessonTip;
  }

  /**
   * 组装"课程时间"
   * @param table
   * @return
   */
  private String buildLessonTimeTip(TableVO table){
    LocalTime startTime = LocalTime.parse(table.getStart());
    LocalTime endTime = LocalTime.parse(table.getEnd());
    long minutesBetween = ChronoUnit.MINUTES.between(startTime, endTime);
    return table.getStartEnd() + "("+ minutesBetween +"分钟)";
  }

  private Long getMillis(String str){
    LocalTime time = LocalTime.parse(str); // 获取当前时间
    LocalDate date = LocalDate.now(); // 获取当前日期
    LocalDateTime dateTime = LocalDateTime.of(date, time); // 组合日期和时间
    ZonedDateTime zonedDateTime = dateTime.atZone(ZoneId.systemDefault()); // 转换为带时区的日期时间
    return zonedDateTime.toInstant().toEpochMilli(); // 获取毫秒时间戳
  }

  @Override
  public void pushMsg(List<Long> classIds) {
    // 给所有登录的机器下发
    Map<String, Long> codeMapId = itTerminalService.codeIdMapByLocationIds(new ArrayList<>(), "班牌");
    Function<String, Message> fc = code -> {
      Response<LessonRemindVO> response = nowLessonRemind(codeMapId.getOrDefault(code, null));
      log.info("响应：{}", JSONObject.toJSONString(response));
      return response;
    };
    try {
      WebSocketHolder.broadcast(fc);
    } catch (Exception e){
      log.error("主动下发失败 课程提醒", e);
    }
  }

  @Override
  public void buildTrigger(List<Long> firstClassIds) {
//    TriggerMsgEngine.addEveryRun(LessonRemindService.class.getSimpleName());
  }


}
